#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
#  GPS2Trackmp4.py
#
#  Copyright 2016 Martin Schöön <martin.schoon@ieee.org>
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#  MA 02110-1301, USA.
#
# This example uses a MovieWriter directly to grab individual frames and
# write them to a file. This avoids any event loop integration, but has
# the advantage of working with even the Agg backend. This is not
# recommended for use in an interactive setting.
#
''' This program reads a GPS data file created by SONY action cameras
and produces a video file on mp4-format. The movie shows track plot and
a moving dot. The frame rate is 1 frame per second.

This program is run from command line as

GPS2Trackmp4.py infilename outfilename
'''

import sys
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import matplotlib.animation as manimation

import ReadNMEA as rn


def plotlimits(lat, lon):
    """Function calculating xmin, xmax, ymin and ymax for plot area for
    best usage of 4:3 format video given lat and lon data. The track
    is centered in the frame."""
    sf = 1.05  # Scale factor used to add a small amount of white-space.
    Lamax = lat.max()
    Lamin = lat.min()
    Lomax = lon.max()
    Lomin = lon.min()
    deltaLa = Lamax - Lamin
    deltaLo = Lomax - Lomin
    Lamean = (Lamax + Lamin)/2.0
    Lomean = (Lomax + Lomin)/2.0

    if deltaLo > 1.3333*deltaLa:
        xmin = Lomean - deltaLo*sf/2.0
        xmax = Lomean + deltaLo*sf/2.0
        ymin = Lamean - 0.375*deltaLo*sf
        ymax = Lamean + 0.375*deltaLo*sf
        return xmin, xmax, ymin, ymax
    else:
        xmin = Lomean - 0.667*deltaLa*sf
        xmax = Lomean + 0.667*deltaLa*sf
        ymin = Lamean - deltaLa*sf/2.0
        ymax = Lamean + deltaLa*sf/2.0
        return xmin, xmax, ymin, ymax


# Read mandatory file names
#

try:
    infilename = sys.argv[1]
    outfilename = sys.argv[2]
except:
    print(usage); sys.exit(1)


# Read and convert data from GPS data file from camera
#

lat, lon, v = rn.ReadGPSData(infilename)  # Acquire data

lat, lon = rn.NMEA2NM(lat, lon)  # Reformat to NM

# Set up video export
#

FFMpegWriter = manimation.writers['ffmpeg']
metadata = dict(title='GPS track', artist='Martin Schoeoen',
                comment='Video overlay')
writer = FFMpegWriter(fps=1, codec='png', metadata=metadata)

# Prepare/format track plot
#

plt.style.use('dark_background')

marker_style = dict(color='red', linestyle=':', marker='o',
                    markersize=15, markerfacecoloralt='gray')
fig = plt.figure()
plt.axis('off')
fig.patch.set_alpha(0.00)
track, = plt.plot(lon, lat, linewidth=4.0, color="orange", alpha=1.0)
l, = plt.plot([], [], **marker_style)  # alpha = opaqueness

xmin, xmax, ymin, ymax = plotlimits(lat, lon)
plt.xlim(xmin, xmax)
plt.ylim(ymin, ymax)

# Moving dot on track
#

x0, y0 = 0, 0

with writer.saving(fig, outfilename, 100):  # last number: scale in %
    for i in range(lat.size):
        x0 = lon[i]
        y0 = lat[i]
        l.set_data([x0], [y0])
        writer.grab_frame()
